package com.sojoys.artifact.third.web.core;

import java.io.File;
import java.net.SocketAddress;
import java.util.List;
import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;

import com.alibaba.fastjson.JSONAware;
import com.alibaba.fastjson.JSONObject;
import com.sojoys.artifact.core.IRequest;
import com.sojoys.artifact.core.IResponse;
import com.sojoys.artifact.third.web.HttpMethod;
import com.sojoys.artifact.third.web.codec.FileItem;

import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.http.FullHttpRequest;
import io.netty.handler.codec.http.HttpHeaders;
import io.netty.handler.codec.http.HttpResponseStatus;
import io.netty.handler.codec.http.cookie.Cookie;

/**
 * 请求上下文
 * 
 * @author zhh
 */
public class NettyHttpContext implements IRequest, IResponse {

	/**
	 * 未完成的CiContext-计数器
	 */
	public static final AtomicInteger counter = new AtomicInteger();

	protected IRequest request;
	protected IResponse response;

	public NettyHttpContext(ChannelHandlerContext ctx, FullHttpRequest req) throws Exception {
		this(new NettyHttpRequest(ctx, req), new NettyHttpResponse(ctx, req));
	}

	public NettyHttpContext(IRequest request, IResponse response) {
		this.request = request;
		this.response = response;
		counter.incrementAndGet();
	}

	public IRequest in() {
		return request;
	}

	public IResponse out() {
		return response;
	}

	public void finish() {
		if (isFinish() == false) {
			counter.decrementAndGet();
			response.finish();
			request.finish();
		}
	}

	public boolean isFinish() {
		return request.isFinish() && response.isFinish();
	}

	@Override
	public synchronized void cleanFinish() {
		if (isFinish() == false) {
			counter.decrementAndGet();
			request.finish();
			response.cleanFinish();
		}
	}

	@Override
	public ChannelHandlerContext ioContext() {
		return response.ioContext();
	}

	private boolean async = false;

	/**
	 * 设置为异步请求, 比如，在专门的线程处理，或者异步等待数据情况时。<br/>
	 * 需要自己在结束后，调用 finish来输出内容<br/>
	 */
	public void setAsync() {
		if (!isFinish()) {
			async = true;
		}
	}

	/**
	 * 是否异步请求
	 * 
	 * @return
	 */
	public boolean isAsync() {
		return async;
	}

	@Override
	public void setStatus(HttpResponseStatus status) {
		response.setStatus(status);
	}

	@Override
	public void setStatus(int statusCode, CharSequence statusInfo) {
		response.setStatus(statusCode, statusInfo);
	}

	@Override
	public void setContentType(CharSequence contentType) {
		response.setContentType(contentType);
	}

	@Override
	public void setHeader(CharSequence name, CharSequence value) {
		response.setHeader(name, value);
	}

	@Override
	public void setCookie(Cookie cookie) {
		response.setCookie(cookie);
	}

	@Override
	public void setCookie(String name, String value) {
		response.setCookie(name, value);
	}

	@Override
	public void setCookie(String name, String value, long maxAge) {
		response.setCookie(name, value, maxAge);
	}

	@Override
	public void setCookie(String name, String value, long maxAge, String path, String domain, boolean secure,
			boolean httpOnly) {
		response.setCookie(name, value, maxAge, path, domain, secure, httpOnly);
	}

	@Override
	public void redirect(CharSequence location) {
		response.redirect(location);
	}

	@Override
	public void redirect(CharSequence location, int httpStatusCode) {
		response.redirect(location, httpStatusCode);
	}

	@Override
	public void sendError(CharSequence errorInfo) {
		response.sendError(errorInfo);
	}

	@Override
	public void sendError(int code, CharSequence errorInfo) {
		response.sendError(code, errorInfo);
	}

	@Override
	public void send(File file) {
		response.send(file);
	}

	@Override
	public void send(File file, int fileCacheSecond) {
		response.send(file, fileCacheSecond);
	}

	@Override
	public void send(JSONAware ret) {
		response.send(ret);
	}

	@Override
	public void send(CharSequence body) {
		response.send(body);
	}

	@Override
	public void send(byte[] body) {
		response.send(body);
	}

	@Override
	public boolean isWroteBody() {
		return response.isWroteBody();
	}

	@Override
	public HttpMethod method() {
		return request.method();
	}

	@Override
	public String refererHost() {
		return request.refererHost();
	}

	@Override
	public String host() {
		return request.host();
	}

	@Override
	public String uri() {
		return request.uri();
	}

	@Override
	public String path() {
		return request.path();
	}

	@Override
	public SocketAddress address() {
		return request.address();
	}

	@Override
	public JSONObject params() {
		return request.params();
	}

	@Override
	public JSONObject post() {
		return request.post();
	}

	@Override
	public JSONObject get() {
		return request.get();
	}

	@Override
	public byte[] body() {
		return request.body();
	}

	@Override
	public List<FileItem> files() {
		return request.files();
	}

	@Override
	public FileItem getFile(String name) {
		return request.getFile(name);
	}

	@Override
	public HttpHeaders headers() {
		return request.headers();
	}

	@Override
	public String getHeader(CharSequence name) {
		return request.getHeader(name);
	}

	@Override
	public Set<Cookie> cookies() {
		return request.cookies();
	}

	@Override
	public Cookie getCookie(CharSequence name) {
		return request.getCookie(name);
	}

	@Override
	public String getCookieValue(CharSequence name) {
		return request.getCookieValue(name);
	}

	@Override
	public String contentType() {
		return request.contentType();
	}

}
